package org.streets.workflow.engine.entities;

import java.io.Serializable;
import java.sql.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

import org.streets.workflow.engine.IProcessInstance;
import org.streets.workflow.engine.ITaskInstance;
import org.streets.workflow.engine.WorkflowException;
import org.streets.workflow.model.WFFormTask;
import org.streets.workflow.model.WFTask;
import org.streets.workflow.model.net.WFActivity;

/**
 * 
 */
@SuppressWarnings("serial")
@Entity
@Table(name = "WF_RT_TASK")
public class TaskInstance implements ITaskInstance, Serializable {

	@Id
	private String id = null;
	@Column
	private String taskModelId = null;
	@Column
	private String activityModelId = null;	
	@Column
	public String processId = null;
	@Column
	private String name = null;
	@Column
	private Integer State = null;
	@Column
	private Boolean suspended = null;
	@Column
	private Date createdTime = null;
	@Column
	private Date startedTime = null;
	@Column
	private Date expiredTime = null;
	@Column
	private Date endTime = null;
	@Column
	private String assignmentStrategy = null;
	@Column
	private String taskType = null;
	@Column
	private String targetActivityId = null;
	@Column
	private String fromActivityId = null;
	@Column
	private Integer stepNum = null;
	@Column
	private Boolean canBeWithdrawn = true;
	
	private transient IProcessInstance process = null;
	private transient WFTask taskModel = null;
	private transient WFActivity activityModel = null;

	public TaskInstance() {
		this.State = ITaskInstance.INITIALIZED;
		this.suspended = false;
	}

	public TaskInstance(IProcessInstance processInstance, WFTask wftask, WFActivity wfactivity) {
		this.State = ITaskInstance.INITIALIZED;
		this.suspended = false;
		this.process = processInstance;
		this.taskModel = wftask;
		this.activityModel = wfactivity;
        this.taskType = wftask.getType();
        this.processId = processInstance.getId();
        this.activityModelId = wfactivity.getId();

        if (WFTask.FORM.equals(taskType)) {
            this.setAssignmentStrategy(((WFFormTask) wftask).getAssignmentStrategy());
            this.setCanBeWithdrawn(true);
        } else {
            this.setCanBeWithdrawn(false);
        }
        this.setCreatedTime(new Date(System.currentTimeMillis()));
        this.setName(wftask.getDisplayName());

        this.setState(ITaskInstance.INITIALIZED);

        this.setTaskModelId(wftask.getId());
		
	}

	public String getId() {
		return this.id;
	}

	public void setId(String id) {
		this.id = id;
	}


	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
    public String getTaskType() {
        return taskType;
    }

    public void setTaskType(String taskType) {
        this.taskType = taskType;
    }
    
	public Integer getState() {
		return this.State;
	}

	public void setState(Integer state) {
		this.State = state;
	}

	public Date getCreatedTime() {
		return this.createdTime;
	}

	public void setCreatedTime(Date createdTime) {
		this.createdTime = createdTime;
	}

	public Date getStartedTime() {
		return this.startedTime;
	}

	public void setStartedTime(Date startedTime) {
		this.startedTime = startedTime;
	}

	public Date getExpiredTime() {
		return this.expiredTime;
	}

	public void setExpiredTime(Date expiredTime) {
		this.expiredTime = expiredTime;
	}

	public Date getEndTime() {
		return this.endTime;
	}

	public void setEndTime(Date endTime) {
		this.endTime = endTime;
	}

	public String getAssignStrategy() {
		return assignmentStrategy;
	}

	public void setAssignmentStrategy(String completionStrategy) {
		this.assignmentStrategy = completionStrategy;
	}

	public Boolean isSuspended() {
		return suspended;
	}

	public Boolean getSuspended() {
		return suspended;
	}

	public void setSuspended(Boolean suspended) {
		this.suspended = suspended;
	}
	
    public String getTaskModelId() {
        return this.taskModelId;
    }

    public void setTaskModelId(String taskId) {
        this.taskModelId = taskId;
    }
    
    public String getActivityModelId() {
        return this.activityModelId;
    }

    public void setActivityModelId(String activityId) {
        this.activityModelId = activityId;
    }

	public IProcessInstance getProcess() {
		return this.process;
	}
	
    public void setProcess(IProcessInstance process) {
        this.processId = process.getId();
        this.process = process;

    }

	public WFTask getTaskModel() throws WorkflowException {
	    if (taskModel == null) {	    
	        taskModel =  (WFTask) process.getModel().findWFElementById(this.getTaskModelId());
	    }
	    return taskModel;
	}

	public WFActivity getActivityModel() throws WorkflowException {
	    if (activityModel == null) {
	        activityModel = (WFActivity) process.getModel().findWFElementById(this.getActivityModelId()); 
	    }
	    return activityModel; 
	}

    public String getFromActivityId() {
        return fromActivityId;
    }

    public void setFromActivityId(String fromActivityId) {
        this.fromActivityId = fromActivityId;
    }
    
	public String getTargetActivityId() {
		return this.targetActivityId;
	}

	public void setTargetActivityId(String s) {
		this.targetActivityId = s;
	}

	public Integer getStepNum() {
		return this.stepNum;
	}

	public void setStepNum(Integer i) {
		this.stepNum = i;
	}

	public Boolean getCanBeWithdrawn() {
		return canBeWithdrawn;
	}

	public void setCanBeWithdrawn(Boolean canBeWithdrawn) {
		this.canBeWithdrawn = canBeWithdrawn;
	}
	
}
